Dataset Readme(Sample)
Wrangled Data
서울특별시 데이터셋
by: 서용훈
※ 본 문서는 PC 환경에 최적화되어있습니다.
1 목차
구상 중입니다.
2 데이터셋 위치
모든 데이터셋은 ‘./data/Datasets/’ 디렉터리 안에 있습니다.
3 정제 데이터셋
데이터셋 랭글링 과정을 담았습니다.
3.1 행정경계 데이터 불러오기
먼저, 분석 스케일의 뼈대가 되는 행정경계 데이터를 불러왔습니다.
3.1.1 사용한 패키지
3.1.2 구
전국 시군구 파일에서 시군구 코드를 기준으로 서울 지역만 추출하는 과정입니다.
3.1.3 행정동
좌표투영이 되어있지 않은 파일이라 구득 웹 사이트(국가공간정보포털 오픈마켓) 상에서 메타데이터를 확인하여, 지리원 표준 좌표계 중 하나인 ‘EPSG:5181’(중부원점, GRS80)로 좌표계를 정의해주고, 불러옴과 동시에 서울 행정동만 추출하였습니다.
3.2 올리브영 매장 - SAMPLE
3.2.1 사용한 패키지
3.2.2 자료의 출처
해당 문서에서 정제한 올리브영 자료는 2020년 7월 19일 기준입니다.
해당 자료는 올리브영 매장안내에서 구득하였습니다.
올리브영 웹 페이지에 게시된 서울시 매장 목록을 사용할 목적으로 html 크롤링을 시도하였으나
위와 같이 스크롤을 모든 항목이 나타날 때까지 해야 되므로, 아래와 같이
스크롤을 하여 모든 항목을 불러온 뒤, 해당 요소를 ’Notepad++’을 사용하여 별도의 html 파일을 생성하였습니다.
3.2.3 정제 과정
먼저, 생성한 html을 블러왔습니다.
불러온 html에서 ‘매장명’과 ’주소’, ‘전화번호’, ’관심매장등록수’를 추출한 뒤, 하나의 데이터프레임을 만들었습니다.
library(tidyverse)
name <- html_nodes(html.olive, css="a") %>%
str_remove('<a href="javascript:;">') %>%
str_remove('</a>')
addr <- html_nodes(html.olive, css=".addr") %>%
str_remove('<p class="addr">') %>%
str_remove('</p>')
ph.numb <- html_nodes(html.olive, css=".call") %>%
str_remove('<div class="call">') %>%
str_remove('</div>')
noi <- html_nodes(html.olive, css=".fv_reShop_in") %>%
html_nodes("span") %>%
as_list() %>%
unlist(use.names=FALSE) %>%
str_remove(',')
olive <- cbind(name,addr,ph.numb,noi) %>%
as.data.frame(stringsAsFactors=FALSE)
olive$noi <- as.integer(olive$noi)
head(olive) name addr
1 은행사거리점 서울특별시 노원구 한글비석로 264 중계그랜드프라자 1층
2 중계역점 서울특별시 노원구 동일로 1335 (상계동)
3 노원역사거리점 서울특별시 노원구 노해로 480
4 노원점 서울특별시 노원구 상계로 65 105호,106호
5 홈플러스중계점 서울특별시 노원구 동일로204가길 12 홈플러스중계점 1층
6 상계보람점 서울특별시 노원구 한글비석로 471
ph.numb noi
1 02-938-9305 1278
2 02-930-2952 518
3 02-934-5123 2365
4 02-935-5290 1948
5 02-948-6960 526
6 02-930-2532 729
위 데이터프레임을 바로 뒤에 언급할 지오코딩 툴을 사용하여 잘못된 주소를 바로잡았습니다.
olive$addr[110] <- as.character("서울특별시 강동구 천호대로 997 지하 1층, 천호엔터식스 012호")
olive$addr[113] <- as.character("서울 종로구 송월길 99 경희궁자이 202동 2132호")
olive$addr[142] <- as.character("만리동2가 229-1")
olive$addr[156] <- as.character("서울 강남구 가로수길 5 1층 올리브영 가로수길입구점")
olive$addr[219] <- as.character("서울특별시 서초구 반포동 19-11")
olive$addr[290] <- as.character("서울특별시 동작구 동작대로 3")
olive$addr[368] <- as.character("서울특별시 강동구 성내로 89")
olive$name[368] <- as.character("티지에스플러스(준비중)")다음의 표에서 검색도 가능합니다.
3.2.4 지오코딩
네이버 클라우드에서 제공하는 지오코딩 API 서비스를 사용하여 좌표를 부여하였습니다.
- 네이버 클라우드
앞서 언급하였듯이, 지오코딩 루프를 돌리면서 주소를 통하여 좌표를 잡지 못하는 데이터를 수정하는 방식으로 주소 무결성 또한 확인하였습니다.
library(httr)
library(XML)
#Client ID 설정
clientId <- "k8g52bouny"
#Client Secret 설정
clientSecret <- "Kadl4ZjbFOhhXXk7806OA24h7sdSEaDYuczHAgaD"
x <- vector(mode = "double", length(olive$addr))
y <- vector(mode = "double", length(olive$addr))
for (i in 1:length(olive$addr)){
#print(i)
apiResult <- httr::GET(
url = "https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode",
httr::add_headers(
`X-NCP-APIGW-API-KEY-ID` = clientId,
`X-NCP-APIGW-API-KEY` = clientSecret
),
query = list(
`query` = olive$addr[i]
)
)
if (apiResult$status_code == "200"){
#print("ResultCode OK!")
result <- rawToChar(apiResult$content)
Encoding(result) <- "UTF-8"
list <- xmlToList(result)
u <- as.numeric(list$addresses$x)
v <- as.numeric(list$addresses$y)
x[i] <- u
y[i] <- v
}else if (apiResult$status_code == "400"){
print(paste("Bad Request Exception in",olive$name[i]))
}else if (apiResult$status_code == "500"){
print(paste("Unexpected Error in",olive$name[i]))
}else{
print("몰라요")
}
}
olive$x <- x
olive$y <- y3.2.5 자료의 공간정보화
먼저 GCS(WGS84)를 사용하여 지오코딩으로 획득한 좌표를 사용하여 공간정보로 변환하였습니다. 또한 행정경계 파일과 좌표체계를 통일하여 공간연산이 가능하게 하였습니다.
3.2.6 공간연산
구, 행정동당 올리브 영의 수를 연산하였습니다.
library(GISTools)
num.gu <- poly.counts(oliveSP, seoulgu)
num.emd <- poly.counts(oliveSP, seoulemd)
head(num.gu) 0 1 2 3 4 5
15 22 12 11 14 8
0 1 2 3 4 5
1 2 0 1 0 1
위에서 연산한 1차 배열의 자료를 두 행정구역 자료의 속성 테이블에 각각 넣어주었습니다.
3.2.7 올리브영 매장 분포 시각화
올리브영 매장 분포
공간연산(구)
3.2.8 정제 자료 저장
다음과 같이 ‘./data/Datasets/Oliveyoung/’ 디렉터리에 데이터프레임을 저장하였고, ‘./data/Datasets/Oliveyoung/shapefile/’ 디렉터리에 공간정보 또한 셰이프파일 포멧으로 저장하였습니다.
# 올리브영 데이터프레임
write_csv(olive, path = "./data/Datasets/Oliveyoung/Oliveyoung.csv", append = FALSE)
# 올리브영 셰이프(점)
writeOGR(oliveSP, paste0(getwd(), "/data/Datasets/Oliveyoung/shapefile"), "Oliveyoung", driver = "ESRI Shapefile",
layer_options = "encoding=UTF-8", overwrite_layer = TRUE)
# 올리브영 점포 수 셰이프(폴리곤, 구)
writeOGR(seoulgu, paste0(getwd(), "/data/Datasets/Oliveyoung/shapefile"), "OliveGu", driver = "ESRI Shapefile",
layer_options = "encoding=UTF-8", overwrite_layer = TRUE)
#올리브영 점포 수 셰이프(폴리곤, 행정동)
writeOGR(seoulemd, paste0(getwd(), "/data/Datasets/Oliveyoung/shapefile"), "OliveEMD", driver = "ESRI Shapefile",
layer_options = "encoding=UTF-8", overwrite_layer = TRUE)
#test <- read_csv("./data/Datasets/Oliveyoung/Oliveyoung.csv")